home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-18 | 61.9 KB | 2,233 lines |
- Newsgroups: comp.sources.unix
- From: brnstnd@nyu.edu (Dan Bernstein)
- Subject: v25i132: Generalized interface to pseudo-tty devices, Part06/09
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: brnstnd@nyu.edu (Dan Bernstein)
- Posting-Number: Volume 25, Issue 132
- Archive-Name: pty4/part06
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 9)."
- # Contents: CALLS CTTYS.draft1 Makefile pty-opts.1 ptytty.c sigsched.3
- # Wrapped by vixie@cognition.pa.dec.com on Wed Feb 19 13:35:05 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'CALLS' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CALLS'\"
- else
- echo shar: Extracting \"'CALLS'\" \(9477 characters\)
- sed "s/^X//" >'CALLS' <<'END_OF_FILE'
- pty uses a bunch of syscalls (42 at last count) and library routines.
- Calls marked with * are BSD-only or otherwise not available on all UNIX
- systems. Calls marked with + are widely available but have different
- behavior on different systems---behavior different enough that pty might
- not work.
- X
- X_exit: used in ptyerr.c for almost all exits. Note that pty does not use
- X stdio in any way.
- X*accept: used in ptycomm.c`comm_accept, to accept a connection for the
- X master on a descriptor created by comm_read
- access: used with F_OK in ptyget.c to check if a pty bank (e.g., ttyq*)
- X exists
- X*bind: used in ptycomm.c`comm_read to create the master's comm socket
- X*bzero: used inside the system's FD_ZERO macro before select
- chdir: used once in the master and once in the sigler, both times in
- X ptymain.c, to switch permanently to PTYDIR.
- close: used throughout the program to get rid of a file descriptor.
- X Note that the return value from close is not checked---there's
- X absolutely no way pty could do anything about the descriptor in
- X case of an error, and it's far more important that the
- X descriptor be freed up than that NFS's perverted idea of UNIX
- X I/O be dealt with.
- X*connect: used in ptycomm.c`comm_write to connect to a running master
- dup: used (1) in ptytty.c to try to find the controlling tty descriptor;
- X (2) in ptyslave.c to move the /dev/ttyxx descriptor to 0/1/2;
- X (3) in ptysecure.c to set up descriptors for /bin/ps
- X*dup2: used in ptymisc.c to move a /dev/null descriptor around
- execve: used in ptysecure.c to invoke /bin/ps
- execvp: used in ptyslave.c to invoke the user's program, after setreuid
- X*fchmod: used in ptysecure.c upon a slave tty descriptor
- X+fcntl: used with F_GETFL in ptymisc.c (and sigsched.c) to see if a
- X descriptor is open
- flock: used in ptymisc.c for generic locking routine (used on log files)
- fork: used in ptymain.c (twice) to create master and slave processes;
- X used in ptysecure.c to invoke /bin/ps for security check
- free: used in ralloc.c`rfree
- X*fstat: used in ptysecure.c upon a slave tty descriptor
- X*getdtablesize: used in slave under -E to close all open descriptors;
- X used in ptymaster.c`closeallbut (which is a royal kludge)
- X*getpgrp: used in ptytty.c`force_fg to plug into TIOCSPGRP; used in
- X ptymaster.c`contchild in preparation for killpg
- getpid: used (1) in the master to fill in a sesslog structure; (2) in
- X ptytty.c`force_fg to plug into getpgrp; (3) in the signaller to
- X send a WINCH to itself after reconnect; (4) in the slave to set
- X its pgrp before exec; (5) in the slave to pass to tctpgrp; (6)
- X to set up numbers for random tty searching; (7) in the master,
- X when fdctrlr asks for its pid; (8) in sigdfl.c to send a signal
- X to itself; (9) in ptysecure.c for various purposes.
- X*getpwnam: used only in username.c
- X*getpwuid: used only in username.c
- X*geteuid: used in ptysecure.c as a secure pseudo-tty owner
- getuid: used once in ptytty.c to initialize a uid variable
- X+ioctl: used in ptytty.c`ioc to control a tty descriptor; about two
- X dozen BSD-specific ioctls are used in ptytty.c
- X+kill: used (1) in the master to tell the child to continue after the
- X sigler says so; (2) in the sigler to tell itself to WINCH after
- X a reconnect; (3) in sigdfl.c to send a signal to itself.
- X*killpg: used in ptymaster.c`contchild to continue the child's process
- X group if a straight kill() failed
- X*listen: used in ptycomm.c to prepare the master's comm socket for
- X connections
- lseek: used in ptylogs.c, sessconnlog.c, and sesslog.c to place a record
- X at a particular spot in a log file
- malloc: used in ralloc.c`ralloc
- X+open: used (1) in ptyget.c with O_RDWR to open the master and slave
- X sides of a tty; (2) in ptylogs.c with O_RDWR, O_RDWR | O_APPEND,
- X and O_WRONLY | O_APPEND to open UTMP_FILE and WTMP_FILE; (3) in
- X ptymisc.c`forceopen upon /dev/null and /, to attempt to make
- X sure a descriptor is in use; (4) in ptyslave.c (twice) to open
- X /dev/tty with O_RDWR; (5) in ptytty.c`tty_getctrl to open
- X /dev/tty; (6) in sessconnlog.c and sesslog.c, with O_WRONLY |
- X O_CREAT and O_WRONLY | O_APPEND | O_CREAT (both mode 0644), to
- X open the sessnow, sesslog, scnow, and sclog system files for
- X update; (7) in ptysecure.c for various purposes.
- pipe: used (1) in ptymain.c to create pipes from the master to the
- X sigler and slave, so that there's no race between the master
- X setting up files and the sigler and slave starting; (2) in
- X ptysigler.c to create the master->sigler and sigler->master
- X pipes just before reconnect; (3) in ptysecure.c to create an
- X output pipe for /bin/ps.
- read
- X*recvmsg: used in ptycomm.c to receive a descriptor from a UNIX-domain
- X socket. Note that recvmsg() is buggy in most BSD variants.
- X*select: used (1) in ptymisc.c to pause briefly; (2) in sigsched.c to
- X check for usable descriptors.
- X*sendmsg: used in ptycomm.c to send a descriptor down a UNIX-domain
- X socket. Note that sendmsg() is buggy in some BSD variants.
- X*setpgrp: used in ptyslave.c to set up pgrp of slave
- X*setreuid: used in ptyslave.c to make sure that slave runs as real uid;
- X used in ptysecure.c to make sure that /bin/ps runs as real uid;
- X used in ptymain.c to make sure that master is safe from user
- X*sigblock: used in sigdfl.c and sigsched.c for various purposes
- X+signal: used in various spots to set handlers to SIG_{IGN,DFL}
- X*sigsetmask: used in sigdfl.c and sigsched.c for various purposes
- X*sigvec: used in sigdfl.c and sigsched.c to install signal handlers
- X*socket: used in ptycomm.c`comm_{read,write} to set up comm socket
- strcpy: used in env.c for various purposes
- strlen: used throughout the code for various purposes
- strncmp: used in env.c and ptylogs.c
- strncpy: used in ptylogs.c, sessconnlog.c, sesslog.c
- time: used in ptymisc.c`now
- unlink: used only in ptycomm.c, upon a restricted pathname, to remove
- X an obsolete communications socket.
- X*wait3: used in both master and sigler to wait for children (in the
- X latter case, simply to get rid of zombies), with NOHANG and
- X UNTRACED.
- write
- X
- Note that pty also depends on environ and errno.
- X
- The BSD-specific calls can be divided into several groups:
- X
- A (pty allocation). Lots of vendors have added pseudo-ttys. In the BSD
- world, everyone simply copied what Berkeley did. Unfortunately, System V
- is graced with at least nine pseudo-tty allocation mechanisms; there are
- probably many more which I haven't seen. ptyget.c and ptysecure.c have
- to be completely rewritten for each new allocation design. On the other
- hand, there must be code which uses the ptys on that system, so this is
- certainly a doable job.
- X
- B (select). select (and the associated FD_ZERO [using bzero], FD_ISSET,
- and FD_SET macros) is the foundation of the sigsched library, which
- literally runs everything. select also uses the largest part of pty's
- run time. It would be incredibly difficult to simulate select() with a
- less powerful mechanism, such as poll(). I would have to be exceedingly
- bored before attempting to port pty to a system without select().
- X
- C (communication, including fd passing). accept, bind, connect, listen,
- recvmsg, sendmsg, and socket are isolated inside ptycomm.c. You can rip
- out the entire ptycomm.c mechanism and replace it with anything which
- X(1) allows client-server connections with some security; (2) lets
- read(), write(), and select() work; (3) provides file descriptor
- passing; (4) allows a two-way connection on a single descriptor. Most
- streams facilities can handle (3). Note that if the file descriptor
- passing mechanism isn't as buggy as BSD's, you can get rid of
- ptymisc.c`gaargh.
- X
- D (job control). getpgrp(), setpgrp(), the TIOCSPGRP and TIOCGPGRP
- ioctls, various signals, kill(,SIGCONT), killpg, and wait3 are all part
- of the BSD job control system. pty puts quite a bit of effort into
- handling job control, but not nearly as much as the previous version. I
- really can't guess what will go wrong if you simply rip out all the job
- control code and replace wait3() with an appropriate wait().
- X
- XE (tty handling). SIGWINCH and some two dozen tty ioctls all depend on
- the BSD tty system. SIGWINCH is easy to take care of---it's already
- X#ifdef'ed for TTY_WINDOWS. (pty works under BSD 4.2, which doesn't have
- SIGWINCH.) The other tty ioctls are isolated inside ptytty.c, which I
- will probably rewrite for POSIX if and when somebody asks me to.
- January 1992 update: Okay, I've now implemented TTY_TERMIO. POSIX, for
- some absolutely idiotic reason, doesn't stick to the traditional header
- files, but TTY_TERMIO should be good enough for systems with System V
- tty handling.
- X
- XF (signal management). sigblock, sigsetmask, sigvec, and good old signal
- are all used throughout the pty code. POSIX can handle all of them, and
- I will do this port soon. System V cannot---it's very important that pty
- have reliable signal handling.
- X
- G (easy stuff). dup2, fcntl(,F_GETFL,0), getdtablesize, getpwnam,
- getpwuid, fchmod, fstat, and setreuid are all reasonably easy to handle.
- dup2() can be written in terms of F_DUPFD for System V; in fact, pty
- only uses it in a situation where it should be a no-op! (See
- ptymisc`forceopen and the calls to forceopen in ptymain.c.) F_GETFL is,
- I believe, available on all modern UNIX-like systems. getdtablesize can
- be replaced by NOFILE. setreuid(uid,uid) is essentially equivalent to
- setuid(uid). getpwnam() and getpwuid() appear on most systems, and when
- they don't appear, they're easy enough to write (just scan /etc/passwd).
- fchmod and fstat can be replaced by chmod and stat---they're only used
- in situations where the pathname is known (viz., a slave tty).
- END_OF_FILE
- if test 9477 -ne `wc -c <'CALLS'`; then
- echo shar: \"'CALLS'\" unpacked with wrong size!
- fi
- # end of 'CALLS'
- fi
- if test -f 'CTTYS.draft1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CTTYS.draft1'\"
- else
- echo shar: Extracting \"'CTTYS.draft1'\" \(9430 characters\)
- sed "s/^X//" >'CTTYS.draft1' <<'END_OF_FILE'
- Controlling Ttys: A UNIX Horror Story
- Daniel J. Bernstein
- draft 1
- X10/6/91
- X
- X
- X1. Introduction
- X
- X ``Normal file access permissions handle security.''
- X ---POSIX.1-1988 rationale, B.7.1.1.4
- X
- When a user logs into a UNIX system, he is assigned a _tty_ which echoes
- and processes his characters, lets him edit command lines, handles flow
- control on output, and so on. The user's shell reads and writes from the
- tty. Messages sent by the ``write'' and ``talk'' user communication
- commands are also sent through the tty. In fact, ttys (also called
- X_terminals_, _teletypes_, and _typewriters_) are the focal point of
- almost all interaction between a user and the system.
- X
- Ttys come in two flavors: hardwired ttys and pseudo-ttys. Hardwired ttys
- are connected directly to a physical device, such as a modem.
- Pseudo-ttys may be dynamically connected to any process. For instance,
- the telnetd program links a pseudo-tty with each network connection.
- X
- Unlike pipes, ttys have traditionally been assigned a name in the
- filesystem: /dev/console, for instance, is a hardwired tty, and
- X/dev/ttyp7 is a pseudo-tty. The primary reason for these files is to
- support user-to-user communication. The system typically assigns
- ownership of tty files to the current user. That way the user can change
- his tty modes to control whether ``write'' and ``talk'' messages are
- allowed.
- X
- Occasionally a program (or more often a script) wants to send messages
- to the current tty, no matter what redirection has been put on stdout
- and stderr. (The author defers judgment on whether this is a sensible
- thing for programs to do.) More often, a user wants to know what the
- current tty is, to keep track of what he's doing. One obvious solution
- to both problems is to keep the current tty in an environment variable,
- like TTY=/dev/ttyp7. Then a ``tty'' program can simply echo $TTY, and
- programs which want to talk to the user can open $TTY.
- X
- Unfortunately, UNIX never acquired such a simple user-mode solution.
- Instead each process was assigned a ``controlling tty'', something which
- the kernel kept track of and treated specially. That is where the horror
- story begins.
- X
- X
- X2. Controlling ttys
- X
- Processes start without a controlling terminal. When a process without a
- controlling tty (also called ``ctty'') opens a tty, it is assigned that
- ctty, and the ctty is preserved through fork() and exec(). Different
- UNIX systems have various methods of removing the association between a
- process and its controlling tty. We will return to this subject below.
- X
- A special file, /dev/tty, is accessible to all processes at all times.
- When a process opens /dev/tty, it gets a valid descriptor to its ctty,
- or ENODEV if it does not have a ctty. The protection on the actual tty
- file is irrelevant to /dev/tty.
- X
- Under BSD 4.2, the controlling tty has almost no effects on job control.
- BSD 4.3 added some rules in the name of job control security. POSIX went
- much farther, and formalized controlling ttys into ``sessions.'' Each
- process is associated with a session, and various ad-hoc session rules
- are thrown in to complicate job control and signal processing in
- general. (For instance, a process can only stop if its parent is in the
- X*same* session but a *different* process group.) The problem of
- supporting job control without losing security became an excuse for
- controlling terminals and sessions.
- X
- At this point we can identify six separate forms of access to a tty
- device, say /dev/ttyp7, by a process:
- X
- X O (ownership) access: uid owns /dev/ttyp7
- X P (protection) access: uid has permision to open /dev/ttyp7
- X C (ctty) access: current ctty is /dev/ttyp7
- X T (/dev/tty) access: file descriptor to /dev/tty, pointing to /dev/ttyp7
- X S (slave) access: file descriptor to /dev/ttyp7 itself
- X M (master) access: file descriptor to /dev/ptyp7 (pseudo-ttys only)
- X
- X(The names ``master'' and ``slave'' are pseudo-tty terminology.)
- The system lets a process acquire access in several ways: A process with
- O access can gain P access. A process with P access can gain S access. A
- process with C access can gain T access. A process with M or S access
- can gain C access. A process can gain M access (by opening /dev/ptyp7)
- if no other process has M access.
- X
- Under BSD, to shed C access, a process must gain T access (i.e., open
- X/dev/tty) and perform the TIOCNOTTY ioctl. Unfortunately, if any process
- applies the TIOCEXCL ioctl to the tty, no process will be able to open
- X/dev/tty itself until some process does TIOCNXCL. A program stuck under
- a tty with TIOCEXCL set has *absolutely no reliable way* to dissociate
- itself from that tty. (Perhaps this is not a surprise given that there
- is also absolutely no reliable way for a process to figure out what tty
- it is associated with in the first place.)
- X
- And the TIOCEXCL problem pales beside the number of twists and turns
- introduced by POSIX. Obviously this is not a simple system to implement,
- use, understand, or make secure.
- X
- X
- X3. Security
- X
- Steve Bellovin pointed out years ago ([]), as did this author ([]), that
- an attacker could abuse controlling ttys to take almost complete control
- of the system. Put simply, it is very difficult to detect, let alone
- revoke, whether another user has S, T, or C access to a tty.
- X
- BSD 4.2 and its descendants have a vhangup() system call meant to revoke
- access to a tty. Unfortunately, it doesn't work on most systems, and
- only revokes S access on the rest. (This author considers vhangup() a
- joke in very poor taste.)
- X
- Several vendors have attempted to fix this problem. The Convex UNIX 8.0
- documentation, for instance, says that the holes are gone. They're not.
- Convex insisted that its system was secure until the author sent
- explicit code showing how to break tty security.
- X
- Similarly, after a series of Internet breakins using tty security holes,
- Sun distributed a patch to their SunOS 4.1 telnetd and rlogind
- supposedly fixing the problems ([]). (It is worth noting that
- essentially the same fix appeared in version 3.0 of the author's pty
- package [] several months before.) Although the patch was enough to
- temporarily stop the attacks, it did not close C access, and hence was
- not enough.
- X
- Version 4.0 of the author's pty package ([]) includes security tests
- which detect all possible forms of tty access, and which work on any BSD
- system. It is obscene that such measures have proven necessary. In the
- meantime, crackers from the Netherlands and elsewhere have broken into
- literally thousands of Internet accounts, taking advantage of tty
- security holes at will.
- X
- X
- X4. Simplifications
- X
- Under SunOS 4.1, BSD 4.4, and a few other systems, T access has been
- removed. A process which opens /dev/tty will get a full-fledged
- descriptor to /dev/ttyp7; there is no longer any distinction between
- X/dev/tty and the real tty file it refers to, except that /dev/tty is
- always completely unprotected.
- X
- Any excuse for controlling terminals or POSIX sessions on the basis of
- job control security is completely invalid. As pointed out by the author
- in [], the job control system can be made much simpler, easier to use,
- and simultaneously completely secure, with absolutely no help from cttys
- or POSIX sessions. As suggested above, the controlling tty can be passed
- in the TTY environment variable. C (and T) access, as well as POSIX
- sessions, can simply disappear.
- X
- X(Apparently the disappearance of cttys and POSIX sessions would remove
- absolutely no functionality, from either the user's or the application's
- point of view; and of course it would make a much cleaner system and
- standard if it were officially adopted. The author would greatly love to
- hear from any proponents of POSIX sessions who can explain what features
- they provide, especially in light of his new, simple, secure job control
- system, when in fact vendors, programmers, and users wouldn't care if
- setsid() became a no-op.)
- X
- XFor backwards compatibility it would be useful to keep a /dev/tty device
- so that programs do not have to be changed to use $TTY. Applications
- running under the author's pty program can normally access the tty
- through descriptor 3, so an easy solution here is to let /dev/tty be a
- simple driver which dup()s fd 3.
- X
- The only other useful function of a controlling terminal---viz., to help
- the user categorize processes---is easily taken care of at user level.
- ps can use $TTY for its output. Accounting could be by pid (as it should
- be) instead of by the marginally useful ac_tty.
- X
- We're still left with O and P access---ttys are still in the filesystem.
- Given fd 3 support, programs which want to talk to the user don't need
- to open() ttys. The other use of ttys in the filesystem is user-to-user
- communication, but there are several replacement communication systems
- which depend on users running their own daemons rather than having a
- writable tty file. So tty files can disappear. Rather than opening tty
- files, programs can create ttys with a new system call. Then ttys will
- be much more like pipes, which may be accessed only through a pair of
- descriptors.
- X
- If these simplifications had been made when UNIX was young, before it
- was used by millions of people, then maybe the controlling terminal
- horror story would not have lasted so long or caused so much damage.
- XFortunately, the story will end soon, as in October 1992 the author will
- distribute code which anyone can use to exploit these holes. Any vendor
- which wants to stay in business will fix its systems long before then.
- X
- X
- References
- X
- XXXX
- END_OF_FILE
- if test 9430 -ne `wc -c <'CTTYS.draft1'`; then
- echo shar: \"'CTTYS.draft1'\" unpacked with wrong size!
- fi
- # end of 'CTTYS.draft1'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(10626 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- CC=cc -s
- OPTMZ=-O
- X# OPTMZ is used below for time-critical modules
- CPP=cc -E
- X# alternative: CPP=/lib/cpp <
- PTYLIBS=
- X
- all: pty clones sessstuff ttymisc misc
- X
- target-list:
- X @echo 'target-list all clones sessstuff ttymisc misc INSTALL CHECKCONF shar clean lint'
- X
- clones: biff mesg wall write lock script users tty who whoami
- X
- sessstuff: sess sesslist sessname sessmenu disconnect reconnect sesswho sesswhere sesskill
- X
- ttymisc: tiocsti condom ttyprotect utmpinit ttydetach checkptys exclon excloff wtmprotate sessrotate sclogrotate sessnowinit scnowinit
- X
- misc: tscript script.tidy waitfor argv0 ctrlv nobuf tplay trecord
- X
- INSTALL: INSTALL.c
- X $(CC) -o INSTALL INSTALL.c
- X
- CHECKCONF: CHECKCONF.c
- X $(CC) -o CHECKCONF CHECKCONF.c
- X
- sessnowinit: sessnowinit.sh
- X $(CPP) sessnowinit.sh | tail -2 | tr -d '"' | sed 's/^X/#/' > sessnowinit
- X chmod 700 sessnowinit
- X
- scnowinit: scnowinit.sh
- X $(CPP) scnowinit.sh | tail -2 | tr -d '"' | sed 's/^X/#/' > scnowinit
- X chmod 700 scnowinit
- X
- sessrotate: sessrotate.sh
- X $(CPP) sessrotate.sh | tail -12 | tr -d '"' | sed 's/^X/#/' > sessrotate
- X chmod 700 sessrotate
- X
- sclogrotate: sclogrotate.sh
- X $(CPP) sclogrotate.sh | tail -12 | tr -d '"' | sed 's/^X/#/' > sclogrotate
- X chmod 700 sclogrotate
- X
- wtmprotate: wtmprotate.sh
- X $(CPP) wtmprotate.sh | tail -12 | tr -d '"' | sed 's/^X/#/' > wtmprotate
- X chmod 700 wtmprotate
- X
- nobuf: nobuf.sh
- X cp nobuf.sh nobuf
- X chmod 700 nobuf
- X
- script.tidy: script.tidy.sh
- X tr '83' '\010\015' < script.tidy.sh > script.tidy
- X chmod 700 script.tidy
- X
- sess: sess.sh
- X cp sess.sh sess
- X chmod 700 sess
- X
- tscript: tscript.sh
- X cp tscript.sh tscript
- X chmod 700 tscript
- X
- script: script.sh
- X cp script.sh script
- X chmod 700 script
- X
- ttyprotect: ttyprotect.sh
- X cp ttyprotect.sh ttyprotect
- X chmod 700 ttyprotect
- X
- condom: ttyprotect.sh
- X cp ttyprotect.sh condom
- X chmod 700 condom
- X
- sesskill: sesskill.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X $(CC) -o sesskill sesskill.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X
- tplay: tplay.o sigsched.o timer.o ralloc.o
- X $(CC) -o tplay tplay.o sigsched.o timer.o ralloc.o
- X
- trecord: trecord.o sigsched.o timer.o ralloc.o
- X $(CC) -o trecord trecord.o sigsched.o timer.o ralloc.o
- X
- ctrlv: ctrlv.o ptymisc.o scan.o
- X $(CC) -o ctrlv ctrlv.o ptymisc.o scan.o
- X
- checkptys: checkptys.o
- X $(CC) -o checkptys checkptys.o
- X
- ttydetach: ttydetach.o env.o ralloc.o
- X $(CC) -o ttydetach ttydetach.o env.o ralloc.o
- X
- excloff: excloff.o
- X $(CC) -o excloff excloff.o
- X
- exclon: exclon.o
- X $(CC) -o exclon exclon.o
- X
- argv0: argv0.o
- X $(CC) -o argv0 argv0.o
- X
- waitfor: waitfor.o
- X $(CC) -o waitfor waitfor.o
- X
- tty: tty.o getopt.o
- X $(CC) -o tty tty.o getopt.o
- X
- utmpinit: utmpinit.o ptymisc.o scan.o
- X $(CC) -o utmpinit utmpinit.o ptymisc.o scan.o
- X
- who: who.o getopt.o fmt.o
- X $(CC) -o who who.o getopt.o fmt.o
- X
- whoami: whoami.o username.o fmt.o scan.o
- X $(CC) -o whoami whoami.o username.o fmt.o scan.o
- X
- users: users.o radixsort.o ralloc.o
- X $(CC) -o users users.o radixsort.o ralloc.o
- X
- lock: lock.o
- X $(CC) -o lock lock.o -lcurses
- X
- sesswhere: sesswhere.o sessconnlog.o getopt.o fmt.o ptymisc.o scan.o
- X $(CC) -o sesswhere sesswhere.o sessconnlog.o getopt.o fmt.o ptymisc.o scan.o
- X
- sesswho: sesswho.o sesslog.o getopt.o ptymisc.o scan.o
- X $(CC) -o sesswho sesswho.o sesslog.o getopt.o ptymisc.o scan.o
- X
- sesslist: sesslist.o ptycomm.o fmt.o getopt.o ptymisc.o scan.o
- X $(CC) -o sesslist sesslist.o ptycomm.o fmt.o getopt.o ptymisc.o scan.o
- X
- disconnect: disconnect.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X $(CC) -o disconnect disconnect.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X
- reconnect: reconnect.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X $(CC) -o reconnect reconnect.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X
- sessmenu: sessmenu.o
- X $(CC) -o sessmenu sessmenu.o
- X
- sessname: sessname.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X $(CC) -o sessname sessname.o ptycomm.o getopt.o env.o ralloc.o ptymisc.o fmt.o scan.o
- X
- biff: biff.o
- X $(CC) -o biff biff.o
- X
- mesg: mesg.o
- X $(CC) -o mesg mesg.o
- X
- tiocsti: tiocsti.o
- X $(CC) -o tiocsti tiocsti.o
- X
- write: write.o fmt.o
- X $(CC) -o write write.o fmt.o
- X
- wall: wall.o fmt.o
- X $(CC) -o wall wall.o fmt.o
- X
- pty: env.o fmt.o getoptquiet.o ptycomm.o ptyerr.o ptyget.o ptylogs.o ptymain.o ptymaster.o ptymisc.o ptysecure.o ptysigler.o ptyslave.o ptytexts.o ptytty.o ralloc.o scan.o sessconnlog.o sesslog.o sigdfl.o sigsched.o username.o
- X $(CC) -o pty env.o fmt.o getoptquiet.o ptycomm.o ptyerr.o ptyget.o ptylogs.o ptymain.o ptymaster.o ptymisc.o ptysecure.o ptysigler.o ptyslave.o ptytexts.o ptytty.o ralloc.o scan.o sessconnlog.o sesslog.o sigdfl.o sigsched.o username.o $(PTYLIBS)
- X
- env.o: env.c
- X $(CC) -c env.c
- X
- fmt.o: fmt.c
- X $(CC) -c fmt.c
- X
- getoptquiet.o: getoptquiet.c
- X $(CC) -c getoptquiet.c
- X
- getopt.o: getopt.c
- X $(CC) -c getopt.c
- X
- ptycomm.o: ptycomm.c
- X $(CC) -c ptycomm.c
- X
- ptyerr.o: ptyerr.c
- X $(CC) -c ptyerr.c
- X
- ptyget.o: ptyget.c
- X $(CC) -c ptyget.c
- X
- ptylogs.o: ptylogs.c
- X $(CC) -c ptylogs.c
- X
- ptymain.o: ptymain.c
- X $(CC) -c ptymain.c
- X
- ptymaster.o: ptymaster.c
- X $(CC) -c ptymaster.c
- X
- ptymisc.o: ptymisc.c
- X $(CC) -c ptymisc.c
- X
- ptysecure.o: ptysecure.c
- X $(CC) -c ptysecure.c
- X
- ptysigler.o: ptysigler.c
- X $(CC) -c ptysigler.c
- X
- ptyslave.o: ptyslave.c
- X $(CC) -c ptyslave.c
- X
- ptytexts.o: ptytexts.c
- X $(CC) -c ptytexts.c
- X
- ptytty.o: ptytty.c
- X $(CC) -c ptytty.c
- X
- ralloc.o: ralloc.c
- X $(CC) -c ralloc.c
- X
- scan.o: scan.c
- X $(CC) -c scan.c
- X
- sessconnlog.o: sessconnlog.c
- X $(CC) -c sessconnlog.c
- X
- sesslog.o: sesslog.c
- X $(CC) -c sesslog.c
- X
- sigdfl.o: sigdfl.c
- X $(CC) -c sigdfl.c
- X
- sigsched.o: sigsched.c
- X $(CC) -c sigsched.c
- X
- username.o: username.c
- X $(CC) -c username.c
- X
- write.o: write.c
- X $(CC) -c write.c
- X
- wall.o: wall.c
- X $(CC) -c wall.c
- X
- tiocsti.o: tiocsti.c
- X $(CC) -c tiocsti.c
- X
- biff.o: biff.c
- X $(CC) -c biff.c
- X
- mesg.o: mesg.c
- X $(CC) -c mesg.c
- X
- sesslist.o: sesslist.c
- X $(CC) -c sesslist.c
- X
- sessname.o: sessname.c
- X $(CC) -c sessname.c
- X
- sessmenu.o: sessmenu.c
- X $(CC) -c sessmenu.c
- X
- disconnect.o: disconnect.c
- X $(CC) -c disconnect.c
- X
- reconnect.o: reconnect.c
- X $(CC) -c reconnect.c
- X
- sesswho.o: sesswho.c
- X $(CC) -c sesswho.c
- X
- sesswhere.o: sesswhere.c
- X $(CC) -c sesswhere.c
- X
- lock.o: lock.c
- X $(CC) -c lock.c
- X
- users.o: users.c
- X $(CC) -c users.c
- X
- tty.o: tty.c
- X $(CC) -c tty.c
- X
- utmpinit.o: utmpinit.c
- X $(CC) -c utmpinit.c
- X
- who.o: who.c
- X $(CC) -c who.c
- X
- whoami.o: whoami.c
- X $(CC) -c whoami.c
- X
- sesskill.o: sesskill.c
- X $(CC) -c sesskill.c
- X
- waitfor.o: waitfor.c
- X $(CC) -c waitfor.c
- X
- ctrlv.o: ctrlv.c
- X $(CC) -c ctrlv.c
- X
- ttydetach.o: ttydetach.c
- X $(CC) -c ttydetach.c
- X
- checkptys.o: checkptys.c
- X $(CC) -c checkptys.c
- X
- excloff.o: excloff.c
- X $(CC) -c excloff.c
- X
- exclon.o: exclon.c
- X $(CC) -c exclon.c
- X
- argv0.o: argv0.c
- X $(CC) -c argv0.c
- X
- radixsort.o: radixsort.c
- X $(CC) $(OPTMZ) -c radixsort.c
- X
- tplay.o: tplay.c
- X $(CC) -c tplay.c
- X
- trecord.o: trecord.c
- X $(CC) -c trecord.c
- X
- timer.o: timer.c
- X $(CC) -c timer.c
- X
- shar: FILES
- X shar `cat FILES` > pty.shar
- X chmod 400 pty.shar
- X
- clean: OBJECTS BINARIES
- X rm -f `cat OBJECTS BINARIES`
- X
- lint:
- X lint -haxc pty*.c getopt.c ralloc.c env.c fmt.c scan.c sessconnlog.c sesslog.c sigdfl.c username.c sigsched.c
- X
- X# automatically generated past this
- X
- CHECKCONF: config/fdsettrouble.h config/genericptr.h config/devmty.h
- CHECKCONF: config/devsty.h config/posix.h config/ptybin.h config/ptydir.h
- CHECKCONF: config/ptyext.h config/ptygroup.h config/ptylongname.h
- CHECKCONF: config/ptymodes.h config/ptyopts.h config/ttyopts.h
- CHECKCONF: config/sessconnfile.h config/sessfile.h
- CHECKCONF: config/utmpfile.h config/wtmpfile.h
- INSTALL: config/ptybin.h config/ptydir.h
- INSTALL: config/ptygroup.h config/sessconnfile.h config/sessfile.h
- INSTALL: config/utmpfile.h config/wtmpfile.h
- INSTALL: config/ptygroup.h
- checkptys.o: config/devmty.h config/devsty.h config/posix.h config/ptybin.h
- checkptys.o: config/ptydir.h config/ptyext.h config/ptygroup.h
- checkptys.o: config/ptymodes.h config/ptyopts.h config/sessconnfile.h
- checkptys.o: config/sessfile.h config/utmpfile.h
- checkptys.o: config/wtmpfile.h
- ctrlv.o: ptymisc.h
- disconnect.o: ptymisc.h ptycomm.h
- disconnect.o: config/ptydir.h getopt.h env.h
- env.o: env.h ralloc.h
- fmt.o: fmt.h
- getopt.o: getopt.h
- getoptquiet.o: getoptquiet.h
- ptycomm.o: fmt.h config/ptyext.h ptycomm.h ptymisc.h
- ptyerr.o: getoptquiet.h fmt.h ptyerr.h ralloc.h
- ptyget.o: ptyget.h
- ptyget.o: config/ptyext.h config/devmty.h config/devsty.h ptysecure.h
- ptylogs.o: fmt.h config/utmpfile.h config/wtmpfile.h
- ptylogs.o: ptymisc.h ptylogs.h config/sysv.h
- ptymain.o: sigsched.h getoptquiet.h ralloc.h env.h fmt.h config/ptydir.h
- ptymain.o: config/ttyopts.h config/ptyopts.h config/posix.h ptyget.h ptytty.h
- ptymain.o: config/ttyopts.h ptylogs.h ptymisc.h
- ptymain.o: ptytexts.h ptycomm.h ptymaster.h ptysigler.h ptyerr.h ptyslave.h
- ptymain.o: sesslog.h sessconnlog.h
- ptymaster.o: sigsched.h ralloc.h
- ptymaster.o: config/ttyopts.h config/ptylongname.h sesslog.h sessconnlog.h
- ptymaster.o: ptyget.h ptymisc.h ptyerr.h ptytty.h
- ptymaster.o: config/ttyopts.h ptycomm.h ptymaster.h
- ptymisc.o: ptymisc.h config/fdsettrouble.h
- ptysecure.o: ptysecure.h ptytty.h
- ptysecure.o: config/ttyopts.h config/ptymodes.h config/ptygroup.h
- ptysigler.o: sigsched.h
- ptysigler.o: sigdfl.h fmt.h sessconnlog.h ptytty.h
- ptysigler.o: config/ttyopts.h ptycomm.h ptymisc.h ptyerr.h config/ttyopts.h
- ptysigler.o: ptysigler.h
- ptyslave.o: fmt.h ptyerr.h
- ptyslave.o: ptyslave.h ralloc.h
- ptytexts.o: ptytexts.h
- ptytty.o: config/genericptr.h
- ptytty.o: config/ttyopts.h ptytty.h config/ttyopts.h
- ralloc.o: ralloc.h sod.h
- reconnect.o: ptymisc.h ptycomm.h
- reconnect.o: config/ptydir.h getopt.h env.h
- scan.o: scan.h
- sessconnlog.o: sessconnlog.h ptymisc.h
- sessconnlog.o: config/sessconnfile.h config/ptyext.h
- sesskill.o: ptycomm.h config/ptydir.h getopt.h
- sesskill.o: env.h
- sesslist.o: config/ptydir.h
- sesslist.o: config/ptylongname.h fmt.h scan.h getopt.h ptycomm.h
- sesslog.o: sesslog.h
- sesslog.o: ptymisc.h config/sessfile.h config/ptyext.h
- sessname.o: ptycomm.h config/ptydir.h
- sessname.o: config/ptylongname.h getopt.h env.h
- sesswhere.o: fmt.h getopt.h sessconnlog.h
- sesswhere.o: config/sessconnfile.h
- sesswho.o: getopt.h sesslog.h config/sessfile.h
- sigdfl.o: sigdfl.h
- sigsched.o: config/fdsettrouble.h sigsched.h
- sigsched.o: ralloc.h sod.h
- timer.o: sigsched.h sod.h
- timer.o: timer.h sigsched.h ralloc.h
- tplay.o: sigsched.h timer.h sigsched.h
- trecord.o: timer.h sigsched.h
- tty.o: getopt.h
- ttydetach.o: env.h config/posix.h
- username.o: username.h fmt.h scan.h
- users.o: config/utmpfile.h
- users.o: radixsort.h sod.h ralloc.h
- utmpinit.o: config/utmpfile.h
- utmpinit.o: ptymisc.h
- wall.o: fmt.h config/utmpfile.h
- who.o: config/utmpfile.h getopt.h fmt.h
- whoami.o: username.h
- write.o: config/utmpfile.h fmt.h
- END_OF_FILE
- if test 10626 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'pty-opts.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pty-opts.1'\"
- else
- echo shar: Extracting \"'pty-opts.1'\" \(9331 characters\)
- sed "s/^X//" >'pty-opts.1' <<'END_OF_FILE'
- X.TH pty-opts 1
- X.SH NAME
- pty-opts \- run a program under a pseudo-terminal session
- X.SH SYNTAX
- pty
- X[
- X\fB\-qQve3EdDjJsStTrR0\fI\fP
- X] [
- X\fB\-h\fIhost\fP
- X] [
- X\fB\-O\fIremote\fP
- X] [
- X\fB\-p[cCdDeEnNrRsS780]\fI\fP
- X] [
- X\fB\-x[cCeEfFrRsSiuUwWxX]\fI\fP
- X] [
- X\fB\-ACHUVW\fI\fP
- X]
- program
- X[
- arg ...
- X]
- X.SH DESCRIPTION
- This man page describes the options
- for the
- X.B pty
- program.
- XFor a general overview of
- X.B pty,
- see the
- X.B pty(1)
- man page.
- XFor the effects of
- X.B pty
- without options,
- see the
- X.B pty-basic(1)
- man page.
- X
- Options
- X.B ACHUVW
- print the authorship notice,
- copyright notice,
- help notice,
- short usage summary,
- version number,
- and warranty information respectively.
- X
- X.B pty
- has quite a few flags,
- processed left to right.
- It processes its options
- with
- X.B getopt.
- It also consistently accepts capital letters to
- turn off options.
- It interprets some switches as turning on or even forcing others,
- as documented below.
- As an example,
- X.B\-d
- forces
- X.B\-T;
- it sets but doesn't force
- X.B\-J.
- To set
- X.B\-d
- and
- X.B\-j,
- use
- X.B\-dj
- in that order.
- X
- Here are the options:
- X.TP 12
- X\fB\-s\fI
- Session.
- When the connection is hung up or manually disconnected,
- X.B pty
- will patiently wait for a
- reconnection.
- X.I program
- won't notice a thing.
- X.B\-s
- sets but does not force
- X.B\-xu.
- It forces
- X.B\-E.
- This mode is described in detail in the
- X.B sess(1)
- man page.
- X.TP
- X\fB\-S\fI
- No session (default).
- When the connection is hung up,
- X.B pty
- will send a HUP to
- X.I program.
- X.B\-S
- sets but does not force
- X.B\-xU.
- X.TP
- X\fB\-d\fI
- X.B pty
- will assume it is already detached from the terminal.
- This forces
- X.B\-T;
- it sets but doesn't force
- X.B\-J.
- Instead of copying pseudo-terminal modes from
- the original terminal,
- X.B pty
- will set up a generic new-discipline line-at-a-time mode,
- as described in the
- X.B ttydfl(7)
- man page.
- X.TP
- X\fB\-D\fI
- X.B pty
- will assume that it is attached to a terminal (default).
- This sets
- X.B\-jt.
- X.TP
- X\fB\-e\fI
- Preserve
- standard error (file descriptor 2)
- and standard tty (file descriptor 3).
- X.TP
- X\fB\-3\fI
- Preserve fd 3, but point fd 2 at the pseudo-terminal.
- X.TP
- X\fB\-E\fI
- Direct both file descriptors to the pseudo-terminal (default).
- X(Actually,
- X.B pty
- will point standard error at the tty by name,
- but fd 3 at /dev/tty,
- so that various
- X.B ioctl()
- commands on fd 3 will work.)
- Also close all higher-numbered file descriptors.
- X.TP
- X\fB\-j\fI
- Job control (default): When
- X.I program
- stops,
- X.B pty
- stops with the same signal.
- When
- X.B pty
- is restarted,
- it restarts
- X.I program.
- Note that
- X.B pty
- handles job control correctly:
- in particular, if it is told to continue while it is in the
- background, it will stop as many times as necessary until it
- is put into the foreground. (Most character-mode programs will
- hang or run in circles in the same situation.)
- X.TP
- X\fB\-J\fI
- No job control.
- If
- X.I program
- stops,
- X.B pty
- will ignore it,
- as if job control didn't exist.
- Note that,
- unlike the previous version of
- X.B pty,
- this version does not restart
- X.I program
- upon a reconnect.
- X.TP
- X\fB\-t\fI
- X.B pty
- will set the
- original terminal to
- no-echo, character-at-a-time mode (default).
- X.TP
- X\fB\-T\fI
- X.B pty
- will not touch the original terminal, if there is one.
- In the simplest case this means that each character will
- be echoed by two tty drivers.
- It is always dangerous to put two programs in a pipe if both
- change tty modes;
- X.B pty,
- X.B vi,
- and
- X.B more
- are examples of such programs. If you use
- X.B pty
- in a pipe
- with another tty-mode-changing program,
- make sure to specify
- X.B\-0
- X(which is an abbreviation for
- X.B\-eSTp0)
- so that
- X.B pty
- will neither affect nor be affected by the other program.
- If you use a pipe of ptys,
- you should probably specify
- X.B\-0
- in all but one.
- See
- X.B condom(1)
- for further details.
- X.TP
- X\fB\-q\fI
- Quiet.
- X.B pty
- will print absolutely nothing on standard error,
- unless
- X.I program
- uses standard error
- and
- X.B\-e
- is set.
- X.B pty
- will communicate strange events through its exit code.
- X.TP
- X\fB\-Q\fI
- Not quiet (default).
- X.B pty
- will generate bits of chatter about interesting
- events,
- such as reconnects.
- X.TP
- X\fB\-v\fI
- Verbose.
- X.B pty
- will blabber on and on and on and on and on and on and on and on.
- It keeps going,
- and going,
- and going,
- and going ...
- X.TP
- X\fB\-r\fI
- Read input (default).
- X.TP
- X\fB\-R\fI
- Don't read input.
- In this case
- X.B pty
- acts much like
- X.B rsh \-n;
- it only forwards output from
- X.I program,
- and does not attempt to read input.
- This forces
- X.B\-T.
- X.TP
- X\fB\-h\fIhost
- Use
- X.I host
- for entries in utmp
- and wtmp.
- By default
- X.B pty
- uses
- pty4.0,
- or pieces together an address from TCPREMOTE if
- it is running under an UCSPI-compliant TCP server.
- This option may be disabled by the system administrator.
- X.TP
- X\fB\-O\fIremote
- Use
- X.I remote
- for entries in scnow and sclog.
- By default
- X.B pty
- uses unknown,
- or pieces together an address from various environment variables
- if it is running under any UCSPI-compliant connection tool.
- This option may be disabled by the system administrator.
- X.TP
- X\fB\-p\fImmm
- Set the
- pseudo-terminal to modes specified by
- X.I m.
- Under
- X.B\-d,
- defaults are taken from the
- current terminal;
- under
- X.B\-D,
- defaults are as below.
- X(See the
- X.B ttydfl(7)
- man page for more information.)
- Predefined modes:
- X.RS
- X.TP 5
- X.I c
- Set cbreak (character-at-a-time) mode.
- X.TP
- X.I C
- Do not set cbreak mode (default).
- X.TP
- X.I d
- Use the new discipline (default, breaking with tradition).
- X.TP
- X.I D
- Use the old discipline, without job control or other fancy tty features.
- X.TP
- X.I e
- XEcho characters (default).
- X.TP
- X.I E
- Do not echo.
- X.TP
- X.I n
- Change return to newline (default).
- X.TP
- X.I N
- Do not change return to newline.
- X.TP
- X.I r
- Set raw mode: do not produce signals, and pass eight-bit characters.
- X.TP
- X.I R
- Set non-raw (``cooked'') mode (default).
- X.TP
- X.I s
- Set line editing modes appropriate for a screen (default).
- X.TP
- X.I S
- Do not set crt line editing modes.
- X.TP
- X.I 7
- Set a 7-bit data path.
- X.TP
- X.I 8
- Set an 8-bit data path (default).
- X.TP
- X.I 0
- An abbreviation for pcrEND.
- X.RE
- X.TP
- X\fB\-x\fIsss
- Use security, experimental, or extended measures specified by
- X.I s.
- Some of these may be required or disabled by your system administrator.
- XFurthermore,
- these options may be changed arbitrarily in future or alternate
- versions of
- X.B pty,
- so you should document any use of
- X.B\-x
- in programs and scripts meant to be portable.
- Predefined values:
- X.RS
- X.TP 5
- X.I c
- Change the ownership and protections of the pty for the current user.
- This option is meaningful only because
- pseudo-ttys are in the filesystem.
- This reflects several errors in the
- UNIX system's pseudo-tty
- model, but it's life.
- X.TP
- X.I C
- Do not change pty ownership (default).
- X.TP
- X.I e
- Do not guarantee readability of stderr to the pseudo-terminal.
- This should be default, but such programs as
- X.I csh
- and
- X.I more
- insist on reading from stderr and dying horribly
- if they fail,
- even though half a teaspoon of common sense indicates
- that the
- X.B standard error
- descriptor
- is actually meant for printing
- X.B errors.
- In any case,
- X.B\-xe
- is useless under
- X.B\-e.
- X.TP
- X.I E
- Open stderr for reading and writing (default).
- X.TP
- X.I f
- XFIONREAD flow-control.
- X.B pty
- will attempt to prevent buffer overflow in cbreak or cooked mode.
- Note that this is not particularly efficient.
- X(This option is rarely appropriate for interactive applications.)
- X.TP
- X.I F
- No flow-control (default).
- In this case
- the tty driver
- will beep and drop characters if there are already 256 in the buffer,
- as usual.
- X.TP
- X.I r
- Random pseudo-terminal searching (default).
- This can provide a huge boost to speed and security.
- If, for instance, there are 200 pseudo-ttys and 100 of them
- are in use,
- other programs will make
- X100
- X.B open()
- calls and will always end up at a predictable spot,
- while it will take
- X.B pty
- an average of just two
- calls to find an unused tty.
- It has been suggested to the author that
- this has not been implemented before
- because programmers don't realize
- the virtues of modularity, are consequently too lazy to
- write something like
- X.B pty,
- and don't want to take the effort for random pty searching
- in every program that uses pseudo-terminals.
- X.TP
- X.I R
- Straight pty searching, from the bottom on up.
- X.TP
- X.I s
- XExtra-secure.
- X.B pty
- always starts by searching for a pseudo-tty which it can unconditionally
- guarantee to be ``clean,'' i.e., not accessible to
- any other users. If it cannot find a clean line, it
- normally prints a warning and then uses any available tty.
- Under this option it will die instead.
- X.TP
- X.I S
- Not extra-secure.
- This is the default.
- X.TP
- X.I i
- Insecure.
- Given this option,
- X.B pty
- won't bother looking for a clean tty first.
- It will take the first tty it can find.
- X.TP
- X.I u
- XEnter login name into /etc/utmp.
- As a rule of thumb,
- you should not do this for non-interactive sessions.
- X.TP
- X.I U
- Do not use utmp (default).
- X.TP
- X.I w
- Make an entry in /usr/adm/wtmp.
- This probably isn't a good idea for general use,
- as
- connection time recorded in
- X.I wtmp
- is often pressed into unfortunate service as
- a senseless basis for charged computer time.
- X.TP
- X.I W
- Do not use wtmp (default).
- X.TP
- X.I x
- Set exclusive use on the pty.
- No processes can open the pty after this;
- X.I program
- can't even reopen
- X/dev/tty!
- X(It can use file descriptor 3 instead.)
- This can be very important for security when
- X.B pty
- has not been installed by the system administrator.
- It should be set all the time, but
- too many programs rely on a filename for the terminal.
- X.TP
- X.I X
- Do not set exclusive use (default).
- X.RE
- X.SH "SEE ALSO"
- pty(1),
- pty-basic(1),
- tty(4)
- END_OF_FILE
- if test 9331 -ne `wc -c <'pty-opts.1'`; then
- echo shar: \"'pty-opts.1'\" unpacked with wrong size!
- fi
- # end of 'pty-opts.1'
- fi
- if test -f 'ptytty.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ptytty.c'\"
- else
- echo shar: Extracting \"'ptytty.c'\" \(9850 characters\)
- sed "s/^X//" >'ptytty.c' <<'END_OF_FILE'
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <sys/ioctl.h>
- X#include <signal.h>
- X#include <errno.h>
- extern int errno;
- X#include "config/genericptr.h"
- X#include "config/ttyopts.h"
- X#include "ptytty.h"
- X
- static int ioc(fd,req,arg) /* non-interruptable ioctl */
- int fd;
- unsigned long req;
- GENERICPTR arg;
- X{
- X int result;
- X do
- X result = ioctl(fd,req,(char *) arg);
- X while ((result == -1) && (errno == EINTR));
- X return result;
- X}
- X
- X#define IOC(f,req,arg) ioc((fd),(unsigned long) (req),(GENERICPTR) (arg))
- X#define IOCR(f,req,arg) { if (IOC(f,req,arg) == -1) return -1; }
- X
- int tty_getctrl()
- X{
- X int fd;
- X int dummy;
- X
- X#define ISTTY(f) (IOC(f,TIOCGPGRP,&dummy) == 0)
- X
- X if ((fd = dup(3)) != -1)
- X if (ISTTY(fd)) return fd; else close(fd);
- X if ((fd = open("/dev/tty",O_RDWR)) != -1)
- X if (ISTTY(fd)) return fd; else close(fd);
- X if ((fd = dup(0)) != -1)
- X if (ISTTY(fd)) return fd; else close(fd);
- X if ((fd = dup(1)) != -1)
- X if (ISTTY(fd)) return fd; else close(fd);
- X if ((fd = dup(2)) != -1)
- X if (ISTTY(fd)) return fd; else close(fd);
- X return -1;
- X}
- X
- int tty_spaceleft(fd)
- int fd;
- X{
- X#ifdef FIONREAD
- X long result;
- X if (IOC(fd,FIONREAD,&result) == -1)
- X return -1;
- X if (result > 200)
- X return 0;
- X return 200 - result;
- X#else
- X errno = EIO;
- X return -1; /*XXX*/
- X#endif
- X}
- X
- int tty_setexcl(fd)
- int fd;
- X{
- X#ifdef TIOCEXCL
- X return IOC(fd,TIOCEXCL,0);
- X /* setting exclusive use is a bit unusual but it works */
- X /* opening /dev/tty should still be allowed, though */
- X#else
- X errno = EIO;
- X return -1;
- X#endif
- X}
- X
- int tctpgrp(fd,pid)
- int fd;
- int pid;
- X{
- X int pgrp;
- X if ((pgrp = getpgrp(pid)) == -1)
- X return -1;
- X return IOC(fdtty,TIOCSPGRP,&pgrp);
- X}
- X
- int tty_forcefg(fd)
- int fd;
- X{
- X int err;
- X signal(SIGTTOU,SIG_DFL);
- X /* XXX: what if TTOU is blocked? what if TTIN applies (e.g., under GNU)? */
- X err = tctpgrp(fd,getpid()); /* could also use ,0 */
- X signal(SIGTTOU,SIG_IGN);
- X return err;
- X}
- X
- int tty_dissoc(fd)
- int fd;
- X{
- X int fdtty;
- X if (fd != -1)
- X if (IOC(fd,TIOCNOTTY,0) == 0)
- X return 0;
- X fdtty = open("/dev/tty",O_RDWR); /* XXX */
- X if (fdtty == -1)
- X if (errno == EBUSY)
- X if (fd != -1)
- X return IOC(fd,TIOCNOTTY,0);
- X else
- X return -1;
- X else
- X return 0; /* XXX: in other words, if we're already dissociated, ok */
- X if (IOC(fdtty,TIOCNOTTY,0) == 0)
- X {
- X close(fdtty);
- X return 0;
- X }
- X close(fdtty);
- X return -1;
- X}
- X
- int tty_getmodes(fd,tmo)
- int fd;
- struct ttymodes *tmo;
- X{
- X#ifdef TTY_TERMIO
- X IOCR(fd,TCGETA,&(tmo->ti))
- X#else
- X IOCR(fd,TIOCGETD,&(tmo->di))
- X IOCR(fd,TIOCGETP,&(tmo->sg))
- X IOCR(fd,TIOCGETC,&(tmo->tc))
- X IOCR(fd,TIOCLGET,&(tmo->lb))
- X IOCR(fd,TIOCGLTC,&(tmo->lt))
- X#endif
- X#ifdef TTY_WINDOWS
- X IOCR(fd,TIOCGWINSZ,&(tmo->wi.ws))
- X#endif
- X#ifdef TTY_AUXCHARS
- X IOCR(fd,TIOCGAUXC,&(tmo->au))
- X#endif
- X return 0;
- X}
- X
- int tty_setmodes(fd,tmo)
- int fd;
- struct ttymodes *tmo;
- X{
- X#ifdef TTY_TERMIO
- X IOCR(fd,TCSETA,&(tmo->ti))
- X#else
- X IOCR(fd,TIOCSETD,&(tmo->di))
- X IOCR(fd,TIOCSETP,&(tmo->sg))
- X IOCR(fd,TIOCSETC,&(tmo->tc))
- X IOCR(fd,TIOCLSET,&(tmo->lb))
- X IOCR(fd,TIOCSLTC,&(tmo->lt))
- X#endif
- X#ifdef TTY_WINDOWS
- X IOCR(fd,TIOCSWINSZ,&(tmo->wi.ws))
- X#endif
- X#ifdef TTY_AUXCHARS
- X IOCR(fd,TIOCSAUXC,&(tmo->au))
- X#endif
- X return 0;
- X}
- X
- int tty_modifymodes(fd,tmonew,tmoold)
- int fd;
- struct ttymodes *tmonew;
- struct ttymodes *tmoold;
- X{
- X#ifdef TTY_TERMIO
- X IOCR(fd,TCSETA,&(tmonew->ti))
- X /* XXX: someone want to flesh this out a bit? */
- X#else
- X if (tmonew->di != tmoold->di)
- X IOCR(fd,TIOCSETD,&(tmonew->di))
- X/* XXX: should make other tests dependent on new discipline? hmmm */
- X if ((tmonew->sg.sg_flags != tmoold->sg.sg_flags)
- X ||(tmonew->sg.sg_ispeed != tmoold->sg.sg_ispeed)
- X ||(tmonew->sg.sg_ospeed != tmoold->sg.sg_ospeed)
- X ||(tmonew->sg.sg_erase != tmoold->sg.sg_erase)
- X ||(tmonew->sg.sg_kill != tmoold->sg.sg_kill))
- X IOCR(fd,TIOCSETP,&(tmonew->sg))
- X if ((tmonew->tc.t_intrc != tmoold->tc.t_intrc)
- X ||(tmonew->tc.t_quitc != tmoold->tc.t_quitc)
- X ||(tmonew->tc.t_startc != tmoold->tc.t_startc)
- X ||(tmonew->tc.t_stopc != tmoold->tc.t_stopc)
- X ||(tmonew->tc.t_eofc != tmoold->tc.t_eofc)
- X ||(tmonew->tc.t_brkc != tmoold->tc.t_brkc))
- X IOCR(fd,TIOCSETC,&(tmonew->tc))
- X if (tmonew->lb != tmoold->lb)
- X IOCR(fd,TIOCLSET,&(tmonew->lb))
- X if ((tmonew->lt.t_suspc != tmoold->lt.t_suspc)
- X ||(tmonew->lt.t_dsuspc != tmoold->lt.t_dsuspc)
- X ||(tmonew->lt.t_rprntc != tmoold->lt.t_rprntc)
- X ||(tmonew->lt.t_flushc != tmoold->lt.t_flushc)
- X ||(tmonew->lt.t_werasc != tmoold->lt.t_werasc)
- X ||(tmonew->lt.t_lnextc != tmoold->lt.t_lnextc))
- X IOCR(fd,TIOCSLTC,&(tmonew->lt))
- X#endif
- X#ifdef TTY_WINDOWS
- X if ((tmonew->wi.ws.ws_xpixel != tmoold->wi.ws.ws_xpixel)
- X ||(tmonew->wi.ws.ws_ypixel != tmoold->wi.ws.ws_ypixel)
- X ||(tmonew->wi.ws.ws_row != tmoold->wi.ws.ws_row)
- X ||(tmonew->wi.ws.ws_col != tmoold->wi.ws.ws_col))
- X IOCR(fd,TIOCSWINSZ,&(tmonew->wi.ws))
- X#endif
- X#ifdef TTY_AUXCHARS
- X if ((tmonew->au.t_usemap != tmoold->au.t_usemap)
- X ||(tmonew->au.t_usest != tmoold->au.t_usest))
- X IOCR(fd,TIOCSAUXC,&(tmonew->au))
- X#endif
- X return 0;
- X}
- X
- void tty_copymodes(tmonew,tmoold)
- struct ttymodes *tmonew;
- struct ttymodes *tmoold;
- X{
- X *tmonew = *tmoold; /* XXX: structure copying */
- X}
- X
- void tty_modes2win(tmo,twi)
- struct ttymodes *tmo;
- struct ttywin *twi;
- X{
- X ;
- X#ifdef TTY_WINDOWS
- X twi->ws.ws_xpixel = tmo->wi.ws.ws_xpixel;
- X twi->ws.ws_ypixel = tmo->wi.ws.ws_ypixel;
- X twi->ws.ws_row = tmo->wi.ws.ws_row;
- X twi->ws.ws_col = tmo->wi.ws.ws_col;
- X#endif
- X}
- X
- void tty_win2modes(twi,tmo)
- struct ttywin *twi;
- struct ttymodes *tmo;
- X{
- X ;
- X#ifdef TTY_WINDOWS
- X tmo->wi.ws.ws_xpixel = twi->ws.ws_xpixel;
- X tmo->wi.ws.ws_ypixel = twi->ws.ws_ypixel;
- X tmo->wi.ws.ws_row = twi->ws.ws_row;
- X tmo->wi.ws.ws_col = twi->ws.ws_col;
- X#endif
- X}
- X
- void tty_zeromode(tmo)
- struct ttymodes *tmo;
- X{
- X /* XXXXX: This is supposed to provide a mode in which the tty does */
- X /* absolutely no processing. I don't think such a mode truly exists. */
- X tty_mungemodes(tmo,3,0,2,0,3,0,3);
- X}
- X
- void tty_mungemodes(tmo,cbreak,new,echo,crmod,raw,crt,p8bit)
- struct ttymodes *tmo;
- int cbreak;
- int new;
- int echo;
- int crmod;
- int raw;
- int crt;
- int p8bit;
- X{
- X#ifdef TTY_TERMIO
- X if (crmod >= 2)
- X tmo->ti.c_iflag = (tmo->ti.c_iflag & ~ICRNL) | (ICRNL * (crmod == 3));
- X if (echo >= 2)
- X tmo->ti.c_lflag = (tmo->ti.c_lflag & ~ECHO) | (ECHO * (echo == 3));
- X if (cbreak >= 2)
- X {
- X tmo->ti.c_lflag = (tmo->ti.c_lflag & ~ICANON) | (ICANON * (cbreak == 2));
- X if (cbreak == 2) { tmo->ti.c_cc[VEOF] = 4; tmo->ti.c_cc[VEOL] = 0; }
- X /* XXX */
- X else { tmo->ti.c_cc[VMIN] = 1; tmo->ti.c_cc[VTIME] = 1; }
- X }
- X if (raw >= 2)
- X {
- X#define NOTIRAW (BRKINT | IGNBRK | IGNPAR | ISTRIP | IXON | IXANY | IXOFF)
- X tmo->ti.c_iflag = (tmo->ti.c_oflag & ~NOTIRAW) | (NOTIRAW * (raw == 2));
- X tmo->ti.c_oflag = (tmo->ti.c_oflag & ~OPOST) | (OPOST * (raw == 2));
- X tmo->ti.c_lflag = (tmo->ti.c_lflag & ~ISIG) | (ISIG * (raw == 2));
- X }
- X if (crt >= 2)
- X {
- X#define CRTECHO (ECHOE | ECHOCTL | ECHOKE)
- X tmo->ti.c_lflag = (tmo->ti.c_lflag & ~CRTECHO) | (CRTECHO * (crt == 3));
- X }
- X /* XXX: p8bit: c_cflag? */
- X /* XXX: new: c_line? */
- X#else
- X if (crmod >= 2)
- X tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CRMOD) | (CRMOD * (crmod == 3));
- X if (echo >= 2)
- X tmo->sg.sg_flags = (tmo->sg.sg_flags & ~ECHO) | (ECHO * (echo == 3));
- X if (cbreak >= 2)
- X tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CBREAK) | (CBREAK * (cbreak == 3));
- X if (raw >= 2)
- X tmo->sg.sg_flags = (tmo->sg.sg_flags & ~RAW) | (RAW * (raw == 3));
- X if (new >= 2)
- X tmo->di = ((new == 3) ? NTTYDISC : OTTYDISC);
- X if (p8bit >= 2)
- X {
- X tmo->lb = (tmo->lb & ~PASS8) | (PASS8 * (p8bit == 3));
- X tmo->sg.sg_flags = (tmo->sg.sg_flags & ~(EVENP | ODDP))
- X | ((EVENP | ODDP) * (p8bit == 2)); /* have to do this for Suns */
- X }
- X if (crt >= 2)
- X tmo->lb = (tmo->lb & ~(CRTBS | CRTERA | CRTKIL | CTLECH))
- X | ((CRTBS | CRTERA | CRTKIL | CTLECH) * (crt == 3));
- X#endif
- X}
- X
- void tty_initmodes(tmo)
- struct ttymodes *tmo;
- X{
- X#ifdef TTY_TERMIO
- X /* Here we specify Ye Standard BSD Terminal Settings in termio format. */
- X tmo->ti.c_iflag =
- X IGNBRK | BRKINT | IGNPAR | ISTRIP | IXON | IXANY | IXOFF;
- X /* XXX: IMAXBEL? */
- X tmo->ti.c_oflag = OPOST | ONLCR;
- X tmo->ti.c_lflag = ISIG | ICANON; /* XXX: | ECHO? */
- X tmo->ti.c_cflag = CS7 | PARENB | PARODD;
- X /* XXX: XTABS? */
- X tmo->ti.c_cc[VINTR] = 3;
- X tmo->ti.c_cc[VQUIT] = 28;
- X tmo->ti.c_cc[VERASE] = 127;
- X tmo->ti.c_cc[VKILL] = 21;
- X tmo->ti.c_cc[VEOF] = 4;
- X tmo->ti.c_cc[VEOL] = 0;
- X tmo->ti.c_cc[VSTART] = 17;
- X tmo->ti.c_cc[VSTOP] = 19;
- X#ifdef VSUSP
- X tmo->ti.c_cc[VSUSP] = 26;
- X#endif
- X#ifdef VDSUSP
- X tmo->ti.c_cc[VDSUSP] = 25;
- X#endif
- X#ifdef VREPRINT
- X tmo->ti.c_cc[VREPRINT] = 18;
- X#endif
- X#ifdef VDISCARD
- X tmo->ti.c_cc[VDISCARD] = 15;
- X#endif
- X#ifdef VWEASE
- X tmo->ti.c_cc[VWERASE] = 23;
- X#endif
- X#ifdef VLNEXT
- X tmo->ti.c_cc[VLNEXT] = 22;
- X#endif
- X#ifdef VSTATUS
- X tmo->ti.c_cc[VSTATUS] = 0;
- X#endif
- X#ifdef VEOL2
- X tmo->ti.c_cc[VEOL2] = 0;
- X#endif
- X#else
- X /* Here we specify Ye Standard BSD Terminal Settings. */
- X
- X tmo->di = OTTYDISC;
- X tmo->sg.sg_ispeed = EXTB;
- X tmo->sg.sg_ospeed = EXTB;
- X tmo->sg.sg_erase = 127; /* del */
- X tmo->sg.sg_kill = 21; /* ^U */
- X tmo->sg.sg_flags = EVENP | ODDP; /* XXX: | XTABS? | ECHO???? */
- X tmo->tc.t_intrc = 3; /* ^C */
- X tmo->tc.t_quitc = 28; /* ^\ */
- X tmo->tc.t_startc = 17; /* ^Q */
- X tmo->tc.t_stopc = 19; /* ^S */
- X tmo->tc.t_eofc = 4; /* ^D */
- X tmo->tc.t_brkc = -1; /* undef */
- X tmo->lb = DECCTQ; /* XXX: | PASS8? contradicts EVENP | ODDP */
- X tmo->lt.t_suspc = 26; /* ^Z */
- X tmo->lt.t_dsuspc = 25; /* ^Y */
- X tmo->lt.t_rprntc = 18; /* ^R */
- X tmo->lt.t_flushc = 15; /* ^O */
- X tmo->lt.t_werasc = 23; /* ^W */
- X tmo->lt.t_lnextc = 22; /* ^V */
- X#endif
- X#ifdef TTY_WINDOWS
- X tmo->wi.ws.ws_xpixel = 0; /* Or read from TERMCAP? Hmmm */
- X tmo->wi.ws.ws_ypixel = 0;
- X tmo->wi.ws.ws_row = 0;
- X tmo->wi.ws.ws_col = 0;
- X#endif
- X#ifdef TTY_AUXCHARS
- X tmo->au.t_usest = 20; /* ^T */
- X tmo->au.t_usemap = UST_LOAD1 | UST_LOAD5 | UST_LOAD15 | UST_RAWCPU
- X | UST_UPTIME | UST_PGRP | UST_CHILDS | UST_PCPU | UST_STATE;
- X#endif
- X}
- END_OF_FILE
- if test 9850 -ne `wc -c <'ptytty.c'`; then
- echo shar: \"'ptytty.c'\" unpacked with wrong size!
- fi
- # end of 'ptytty.c'
- fi
- if test -f 'sigsched.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sigsched.3'\"
- else
- echo shar: Extracting \"'sigsched.3'\" \(10067 characters\)
- sed "s/^X//" >'sigsched.3' <<'END_OF_FILE'
- X.TH sigsched 3
- X.SH NAME
- sigsched \- signal-schedule (non-preemptive threads) library
- X.SH SYNTAX
- X.B #include <sigsched.h>
- X
- ss_sig *\fBss_asap()\fR;
- X.br
- ss_sig *\fBss_signal(\fIsigno\fB)\fR;
- X.br
- ss_sig *\fBss_sigread(\fIfd\fB)\fR;
- X.br
- ss_sig *\fBss_sigwrite(\fIfd\fB)\fR;
- X.br
- ss_sig *\fBss_sigexcept(\fIfd\fB)\fR;
- X
- int \fBss_addsig(\fIsigno\fB)\fR;
- X
- int \fBss_schedvwait(\fIsig,t,flagi,i,p,wait\fB)\fR;
- X.br
- int \fBss_schedwait(\fIsig,t,i,wait\fB)\fR;
- X.br
- int \fBss_sched(\fIsig,t,i\fB)\fR;
- X
- int \fBss_schedonce(\fIsig,t,i\fB)\fR;
- X
- int \fBss_unschedv(\fIsig,t,flagi,i,p\fB)\fR;
- X.br
- int \fBss_unsched(\fIsig,t,i\fB)\fR;
- X
- void \fBss_externsetsig(\fIsig,x\fB)\fR;
- X
- int \fBss_exec()\fR;
- X
- void \fBss_forcewait()\fR;
- X.br
- void \fBss_unforcewait()\fR;
- X
- ss_thread \fI*t\fP;
- X.br
- ss_sig \fI*sig\fP;
- X.br
- ss_extern \fI*x\fP;
- X.br
- int \fIflagi\fP;
- X.br
- int \fIsigno\fP;
- X.br
- int \fIfd\fP;
- X.br
- ss_id \fIi\fP;
- X.br
- ss_idptr \fIp\fP;
- X.br
- int \fIwait\fP;
- X.SH DESCRIPTION
- X.B sigsched
- implements the signal-schedule programming model,
- otherwise known as non-preemptive threads,
- otherwise known as event-based programming.
- A thread is scheduled to execute upon receipt of a signal
- X(occurrence of an event).
- Separate threads do not interrupt each other.
- All they can do is schedule more threads.
- X
- X.B sigsched
- supports far more flexible signals than C normally provides
- under UNIX.
- X``File descriptor 2 is writable'' is a signal, for example.
- XFurthermore, threads do not have to be written to handle a
- signal at any moment, so code written to use
- X.B sigsched
- can be fully optimized.
- In contrast, preemptive thread models (including
- UNIX's usual signal handling) prevent optimizations involving global
- variables.
- X
- In general, a ``signal'' is any persistent condition.
- The ``file descriptor 2 is writable'' signal starts when the pipe
- is created, persists at least until the next I/O, finishes when the pipe is
- written to capacity, restarts when the pipe is read, and so on.
- UNIX signals are examples of
- X.I thread-lowered signals.
- XFor example, SIGINT starts (is raised) when some process executes
- kill(pid,SIGINT),
- and finishes (is lowered) just before process pid calls the appropriate
- signal handler (thread).
- Note that if another process calls
- kill(pid,SIGINT)
- before the first one is delivered,
- the signal merely persists.
- It is not delivered twice, as after the first delivery the
- signal condition has been turned off and can't be redelivered.
- Any number of kill()s may be absorbed into
- one delivery in this way.
- X
- With
- X.B sigsched,
- the program can schedule a thread to execute upon receipt of a signal.
- X.B ss_schedvwait()
- and
- X.B ss_unschedv()
- schedule and unschedule threads.
- X.B ss_exec()
- then executes one scheduled thread after another, as described below.
- It exits when there are no ``important'' threads left to execute.
- X
- X.B ss_schedvwait(\fIsig,t,flagi,i,p,wait\fB)
- schedules the thread
- X.I t
- to execute with integer identifier
- X.I i
- or pointer identifier
- X.I p
- as soon as condition
- X.I sig
- exists.
- This is an ``important'' thread if
- X.I wait
- is nonzero.
- X.I sig
- is of type
- X.B ss_sig *;
- various functions produce signals of this type.
- X.I t
- is of type
- X.B ss_thread *,
- defined as a function returning void;
- it is called as
- X.I t(i)
- if
- X.I flagi
- is nonzero,
- or
- X.I t(p)
- if
- X.I flagi
- is zero.
- X.I i
- is an integer,
- which must be zero if
- X.I flagi
- is;
- X.I p
- is a character pointer,
- which must be a null pointer if
- X.I flagi
- is nonzero.
- X.B <sigsched.h>
- defines the
- X.B ss_sig
- and
- X.B ss_thread
- types;
- it also abbreviates
- int as
- X.B ss_id
- and char * as
- X.B ss_idptr.
- X.B ss_schedvwait
- normally returns 0, but will return -1
- in case of a memory allocation failure.
- X
- X.B ss_unschedv(\fIsig,t,flagi,i,p\fB)
- unschedules the thread
- X.I t
- previously scheduled to execute with identifier
- X.I i
- or
- X.I p
- as soon as condition
- X.I sig
- existed.
- X.I flagi,
- X.I i,
- and
- X.I p
- must follow the same rules as above.
- X.B ss_unschedv
- returns 0 if the unschedule was successful,
- X1 if there was no such thread.
- The effects are currently undefined if a thread is scheduled
- more than once for the same signal with the same identifier.
- X
- X.B ss_exec()
- executes one thread after another, with no interruptions.
- It calls
- X.I t(id)
- only if, for some signal
- X.I sig,
- X(1)
- X.I t(id)
- is scheduled to execute upon
- X.I sig;
- X(2) condition
- X.I sig
- has existed sometime between the end of the last call
- of a thread scheduled upon
- X.I sig
- and the beginning of this call to
- X.I t(id).
- If a
- thread has just finished executing and
- X.B ss_exec
- can call one or more
- threads under the above restrictions, it will choose one and call that,
- unless every scheduled thread has a wait value of 0
- X(i.e., there are no important threads scheduled).
- In the latter case
- X(including, for example, when there are no threads scheduled at all),
- X.B ss_exec()
- immediately returns 0.
- It returns -1 in case of a memory allocation
- failure; in that case its internal structures may be permanently
- corrupted, and
- X.B ss_exec
- may not be called again in the same program.
- X
- If no threads can execute at a given moment,
- but if some thread is
- scheduled with a non-zero wait value,
- X.B ss_exec
- has to wait for a signal
- to arrive.
- As an optimization,
- it will block the process until some
- thread can execute,
- rather than actively polling the set of signals.
- X
- Note that if several threads are scheduled to execute upon one signal,
- and the signal suddenly exists, one of the threads will execute.
- If the
- signal turns off before the end of that thread, the other threads
- scheduled upon the signal will not execute.
- This is always true for
- thread-lowered signals.
- This behavior stands in
- marked contrast to the behavior of interrupts---upon an interrupt,
- all the scheduled threads would be executed.
- X
- XEach signal provides its own scheduling guarantees.
- XFor instance, under
- this implementation,
- any (waiting) thread scheduled on the signal
- X.I ss_asap()
- will in fact execute at some point, provided that no thread
- blocks or loops forever.
- There is no way to keep pushing
- X.I ss_asap()
- farther and farther into the future by scheduling other threads.
- On the other hand,
- X.I ss_asap()
- will never flush out the other builtin signals.
- X
- X.B sigsched
- provides several builtin signals:
- X.B ss_asap()
- returns a (pointer to a) signal which always exists.
- X.B ss_signal(\fIsigno\fB)
- returns a thread-lowered signal which is true when UNIX signal
- X.I signo
- is received.
- X.B ss_sigread(\fIfd\fB)
- returns a signal which is true when
- X.I fd
- is open and readable, as defined by
- X.I select();
- similarly for
- X.B ss_sigwrite
- and
- X.B ss_sigexcept.
- X
- In order for
- X.B sigsched
- to handle UNIX signal
- X.I signo,
- you must call
- X.B ss_addsig(\fIsigno\fB)
- before calling
- X.B ss_exec().
- X.B ss_addsig
- will discard the old signal handler;
- later,
- X.B ss_exec
- will not restore the handler upon exiting, and may
- leave the signal blocked or unblocked.
- X.B ss_addsig
- will return 0 normally,
- X-1 if
- X.I signo
- is not in the right range for signals.
- If another library makes use of
- X.B ss_signal
- with
- X.B sigsched,
- it should provide a mandatory initialization routine
- which calls
- X.B ss_addsig.
- X
- X.B ss_schedvwait
- and
- X.B ss_unschedv
- can be abbreviated in common cases.
- X.B ss_schedwait(\fIsig,t,i,wait\fB)
- is the same as
- X.B ss_schedvwait(\fIsig,t,1,i,(ss_idptr)0,wait\fB).
- X.B ss_sched(\fIsig,t,i\fB)
- is the same with
- X.I wait
- set to 0; it is commonly used for
- handling user signals.
- X.B ss_unsched(\fIsig,t,i\fB)
- is the same as
- X.B ss_unschedv(\fIsig,t,1,i,(ss_idptr)0\fB).
- X
- X.B ss_schedonce(\fIsig,t,i\fB)
- is similar to
- X.B ss_sched
- but is in fact implemented on top of
- X.B ss_schedvwait
- with an independent mechanism.
- XEach call to
- X.B ss_schedonce
- schedules
- X.I t
- upon a new signal which starts when
- X.I sig
- does and exists only until
- X.I t(i)
- is executed.
- After the first execution the new signal disappears.
- The new signal cannot be unscheduled.
- X
- X.B ss_forcewait()
- tells
- X.B sigsched
- that something important is going on outside
- X.B sigsched
- and that
- X.B ss_exec
- should not exit.
- X.B ss_unforcewait()
- negates a previous
- X.B ss_forcewait().
- X.B ss_forcewait()
- and
- X.B ss_unforcewait()
- control a counter, not a flag, so independent
- libraries can use them, but each library should
- be careful to use as many of one call as of the other.
- These functions must not be used outside
- X.B ss_exec().
- X
- X.B ss_externsetsig(sig,x)
- creates a new signal
- in the
- X.B ss_sig
- pointed to by
- X.I sig.
- X.I x
- points to an
- X.B ss_extern,
- which is defined as follows in
- X.B <sigsched.h>:
- X.PP
- X.EX
- typedef struct {
- X int (*sched)();
- X int (*unsched)();
- X union { int n; char *c; } u;
- X} ss_extern;
- X.EE
- X.PP
- X.I sched
- must be filled in with a scheduling function,
- which is called as
- X.I (*sched)(x,t,flagi,i,p,wait)
- whenever
- X.B ss_schedvwait(\fIsig,t,flagi,i,p,wait\fB)
- is called;
- similarly for
- X.I unsched.
- Use of
- X.I u
- is up to the caller.
- X.I sched
- and
- X.I unsched
- must observe the same rules as
- X.B ss_schedvwait
- and
- X.B ss_unschedv
- on any other signals: i.e., they must schedule threads upon
- a persistent condition, make sure that
- X.I ss_exec
- does not exit if
- any important threads are scheduled, etc.
- Note that
- X.B ss_externsetsig
- records
- X.I x
- in
- X.I sig,
- so
- X.I x
- must point either to static memory or to
- memory which remains allocated as long as
- any thread is scheduled or executing upon
- X.I sig.
- Memory management of the
- X.I sig
- structure itself is up to the caller.
- X
- It is recommended that library
- X.I foo
- define a
- X.B foo_sig
- structure, which contains
- X.B ss_sig
- X.I sig,
- X.B ss_extern
- X.I x,
- and any other necessary information for the signals defined by
- X.I foo.
- Then
- X.B foo_setsig(\fI&fsig,otherinfo\fB),
- where
- X.I fsig
- is a
- X.B foo_sig,
- should set up the
- X.I otherinfo,
- set
- X.I fsig.x.u.c
- to
- X.I &fsig,
- set
- X.I fsig.x.sched
- and
- X.I fsig.x.unsched
- appropriately,
- and
- finish with
- X.B ss_externsetsig(&fsig.sig,&fsig.x).
- That way the user can use
- X.I &fsig.sig
- as the signal argument to
- X.B sigsched
- functions,
- and when
- X.I foo's
- scheduling routines are passed
- X.I &fsig.x
- as a first argument,
- they can get to
- X.I otherinfo
- through
- X.I fsig.x.u.c.
- X
- X.B sigsched
- uses
- X.B ralloc
- for all allocation.
- X.SH VERSION
- sigsched 1.1, August 25, 1991.
- X.SH AUTHOR
- Placed into the public domain by Daniel J. Bernstein.
- X.SH "SEE ALSO"
- select(2),
- sigvec(2),
- ralloc(3)
- END_OF_FILE
- if test 10067 -ne `wc -c <'sigsched.3'`; then
- echo shar: \"'sigsched.3'\" unpacked with wrong size!
- fi
- # end of 'sigsched.3'
- fi
- echo shar: End of archive 6 \(of 9\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-